java Copy-On-Write并发容器

前言

在JDK1.5以上版本中,提供了CopyOnWriteArrayList,CopyOnWriteArraySet两种并发容器。采用读写分离的思想(读操作在元数据中操作,写操作则在副本中操作),降低锁冲突,提高并发性。

原理剖析

CopyOnWriteArrayList 部分JDK源码:

public class CopyOnWriteArrayList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
private static final long serialVersionUID = 8673264195747942595L;

/** The lock protecting all mutators */
transient final ReentrantLock lock = new ReentrantLock();

/** The array, accessed only via getArray/setArray. */
private volatile transient Object[] array;

/**
* Gets the array. Non-private so as to also be accessible
* from CopyOnWriteArraySet class.
*/
final Object[] getArray() {
return array;
}

/**
* Sets the array.
*/
final void setArray(Object[] a) {
array = a;
}

/**
* 读取操作(没有加锁)
*/
public E get(int index) {
return (E)(getArray()[index]);
}

/**
*写操作(加锁的目的:防止并发量大时,产生过多的元数据副本,耗内存)
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
//对元数据进行拷贝
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;//操作副本
setArray(newElements);//修改元数组引用为副本引用
return true;
} finally {
lock.unlock();
}
}
}

总结

对于读多写少的场景(例如:缓存),可以有效减少锁冲突,提示系统并发能力。